package com.tarena.lbs.content.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.github.pagehelper.PageInfo;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.attach.pojo.param.PicUpdateParam;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.common.principle.UserPrinciple;
import com.tarena.lbs.common.utils.AuthenticationContextUtils;
import com.tarena.lbs.content.dao.mapper.CategoryMapper;
import com.tarena.lbs.content.dao.repository.ActionESRepository;
import com.tarena.lbs.content.dao.repository.ArticleESRepository;
import com.tarena.lbs.content.dao.repository.ArticleRepository;
import com.tarena.lbs.content.dao.repository.CategoryESRepository;
import com.tarena.lbs.content.pojo.param.ArticleActionParam;
import com.tarena.lbs.content.pojo.param.ArticleContentParam;
import com.tarena.lbs.content.pojo.po.ActionSearchPO;
import com.tarena.lbs.content.pojo.po.ArticleSearchPO;
import com.tarena.lbs.content.pojo.query.ArticleQuery;
import com.tarena.lbs.content.pojo.vo.ArticleActionPageResultVO;
import com.tarena.lbs.content.pojo.vo.ArticleActionVO;
import com.tarena.lbs.content.pojo.vo.ArticleVO;
import com.tarena.lbs.content.service.ArticleService;
import com.tarena.lbs.content.utils.SequenceGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ArticleServiceImpl implements ArticleService {

    @DubboReference
    private AttachApi attachApi;

    @Autowired
    private ArticleESRepository articleESRepository;
    @Autowired
    private ActionESRepository actionESRepository;
    @Autowired
    private ArticleRepository articleRepository;
    @Autowired
    private CategoryESRepository categoryESRepository;

    @Override
    public void addArticle(ArticleContentParam param) throws BusinessException {
        log.debug("文章保存业务处理,入参:{}",param);
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        if (userPrinciple == null) {
            throw new BusinessException("-1","请登录用户");
        }
        ArticleSearchPO po = new ArticleSearchPO();
        BeanUtils.copyProperties(param,po);
        po.setCreateTime(new Date());
        po.setUserId(userPrinciple.getId());
        if (param.getLatitude() != null && param.getLongitude() != null){
            po.setLocation(param.getLatitude() + "," + param.getLongitude());
        }
        //TODO 调用活动服务添加活动信息

        // 如果是新增文章（ID为null），则生成递增的数字ID
        if (po.getId() == null) {
            // 查询当前最大的ID
            Integer maxId = getMaxId();
            // 新ID为最大ID+1，如果没有任何记录，则从1开始
            po.setId(maxId + 1);
        }
        po.setArticleUsername(userPrinciple.getNickname());
        //TODO 调用附件服务插入图片
       //List<PicUpdateParam> picParams = param.();
       // attachApi.batchUpdateBusiness(picParams);
        articleESRepository.save(po);
    }

    @Override
    public ArticleVO detail(String id) throws BusinessException {
        log.debug("文章详情业务处理,入参:{}",id);
        //通过id在ES中查询文章详情并返回ArticleVO的对象
        Optional<ArticleSearchPO> optional = articleESRepository.findById(id);
        if (!optional.isPresent()) {
            return null;
        }
        ArticleSearchPO po = optional.get();
        po.setAccessCount(po.getAccessCount() + 1);
        articleESRepository.save(po);
        ArticleVO vo = new ArticleVO();
        BeanUtils.copyProperties(po,vo);
        log.debug("文章详情业务处理,返回结果:{}",vo);
        return vo;
    }

    @Override
    public PageResult<ArticleVO> pageList(ArticleQuery articleQuery) {
        log.info("分页查询文章列表:{}",articleQuery);
        PageResult<ArticleVO> voPage = new PageResult<>();
        PageInfo<ArticleSearchPO> pageInfo = articleRepository.pageList(articleQuery);
        voPage.setPageNo(pageInfo.getPageNum());
        voPage.setPageSize(pageInfo.getPageSize());
        voPage.setTotal(pageInfo.getTotal());
        List<ArticleVO> vos = null;
        List<ArticleSearchPO> pos = pageInfo.getList();
        if (CollectionUtils.isNotEmpty(pos)) {
            vos = pos.stream().map(po -> {
                ArticleVO vo = new ArticleVO();
                BeanUtils.copyProperties(po, vo);
                vo.setArticleCategory(categoryESRepository.findById(po.getArticleCategoryId()).get().getCategoryName());
                return vo;
            }).collect(Collectors.toList());
        }
        voPage.setObjects(vos);
        return voPage;
    }



    @Override
    public void articleBehavior(ArticleActionParam param) throws BusinessException {
        log.debug("用户行为记录业务处理,入参:{}",param);
        // 校验参数，文章ID不能为空
        if (param.getId() == null) {
            throw new BusinessException("-1","传入文章ID");
        }

        // 根据文章ID查询文章，并校验是否存在
        Optional<ArticleSearchPO> articlePOOptional = articleESRepository.findById(param.getId().toString());
        if (articlePOOptional.isEmpty()) {
            throw new BusinessException( "-2", "文章不存在");
        }
        ArticleSearchPO articlePO = articlePOOptional.get();

        // 获取当前登录用户，并校验登录状态
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        if (userPrinciple == null) {
            throw new BusinessException("-3", "请登录用户");
        }

        // 收集待处理的行为类型
        List<Integer> behaviorTypes = new ArrayList<>();
        if (param.getAction() != null) behaviorTypes.add(param.getAction());
        if (param.getBehavior() != null) behaviorTypes.add(param.getBehavior());

        // 循环处理每个行为类型
        for (Integer behaviorType : behaviorTypes) {
            // 创建独立的行为记录对象
            ActionSearchPO actionPO = buildActionPO(articlePO, userPrinciple);
            // 处理单个行为
            singleBehavior(behaviorType, articlePO, actionPO, param);
        }
    }

    @Override
    public ArticleActionPageResultVO getBehaviorLists(ArticleQuery query) throws BusinessException {
        log.debug("获取用户有操作行为的文章列表:{}", query);
        ArticleActionPageResultVO vo = new ArticleActionPageResultVO();
        
        // 获取当前登录用户
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        if (userPrinciple == null) {
            throw new BusinessException("-1", "请登录用户");
        }
        
        Integer userId = userPrinciple.getId();
        Integer pageNo = query.getPageNo() != null ? query.getPageNo() : 1;
        Integer pageSize = query.getPageSize() != null ? query.getPageSize() : 10;
        
        // 查询点赞行为的文章列表
        PageInfo<ArticleSearchPO> likePageInfo = articleRepository.getArticlesByUserBehavior(userId, 1, pageNo, pageSize);
        PageResult<ArticleActionVO> likePageResult = convertToActionPageResult(likePageInfo);
        vo.setLikeFuturePageResult(likePageResult);
        
        // 查询收藏行为的文章列表
        PageInfo<ArticleSearchPO> collectPageInfo = articleRepository.getArticlesByUserBehavior(userId,2, pageNo, pageSize);
        PageResult<ArticleActionVO> collectPageResult = convertToActionPageResult(collectPageInfo);
        vo.setCollectFutureOPageResult(collectPageResult);
        
        // 查询评论行为的文章列表
        PageInfo<ArticleSearchPO> commentPageInfo = articleRepository.getArticlesByUserBehavior(userId,3, pageNo, pageSize);
        PageResult<ArticleActionVO> commentPageResult = convertToActionPageResult(commentPageInfo);
        vo.setCommentFuturePageResult(commentPageResult);
        
        return vo;
    }

    @Override
    public Set<String> articleLabels(ArticleQuery articleQuery) {
        log.debug("文章标签列表查询:{}",articleQuery);
        
        // 获取当前登录用户信息
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        if (userPrinciple != null) {
            // 如果用户已登录，设置用户ID
            articleQuery.setUserId(userPrinciple.getId());
            
            // 如果查询参数中没有提供位置信息，可以考虑使用用户常用位置
            // 这里暂时留空，可以根据业务需求添加获取用户常用位置的逻辑
        }
        
        Set<String> labels = articleRepository.articleLabels(articleQuery);
        if (CollectionUtils.isNotEmpty(labels)) {
            log.debug("文章标签列表查询结果:{}",labels);
            return labels;
        }else {
            return new HashSet<>(); // 返回空集合而不是null
        }

    }

    @Override
    public ArticleVO updateArticle(ArticleContentParam param) throws BusinessException {
        log.debug("文章更新业务处理,入参:{}",param);

        // 从ES中获取原文档
        Optional<ArticleSearchPO> optionalPo = articleESRepository.findById(param.getId().toString());
        if (!optionalPo.isPresent()) {
            throw new BusinessException("-1", "未找到对应的文章");
        }

        ArticleSearchPO po = optionalPo.get();

        // 更新文章状态及其他属性
        if (param.getId() != null){
            po.setId(param.getId());
        }
        if (param.getArticleTitle() !=  null){
            po.setArticleTitle(param.getArticleTitle());
        }
        if (param.getArticleCategoryId() != null){
            po.setArticleCategoryId(param.getArticleCategoryId());
        }
        if (param.getArticleLabel() != null){
            po.setArticleLabel(param.getArticleLabel());
        }
        if (param.getArticleDigest() != null){
            po.setArticleDigest(param.getArticleDigest());
        }
        if (param.getArticleCover() != null){
            po.setArticleCover(param.getArticleCover());
        }
        if (param.getArticleMainPic() != null){
            po.setArticleMainPic(param.getArticleMainPic());
        }
        if (param.getArticleDetail() != null){
            po.setArticleDetail(param.getArticleDetail());
        }
        if (param.getShopId() != null){
            po.setShopId(param.getShopId());
        }
        if (param.getActivityWord() != null){
            po.setActivityWord(param.getActivityWord());
        }
        if (param.getActivityId() != null){
            po.setActivityId(param.getActivityId());
        }
        if (param.getLatitude() != null){
            po.setLatitude(param.getLatitude());
        }
        if (param.getLongitude() != null){
            po.setLongitude(param.getLongitude());
        }
        if (param.getArticleStatus() != null){
            po.setArticleStatus(param.getArticleStatus());
        }
        if (param.getAccessCount() != null){
            po.setAccessCount(param.getAccessCount());
        }
        if (param.getLikeCount() != null){
            po.setLikeCount(param.getLikeCount());
        }
        if (param.getFavoriteCount() != null){
            po.setFavoriteCount(param.getFavoriteCount());
        }
        if (param.getSource() != null){
            po.setSource(param.getSource());
        }
        po.setUpdateTime(new Date());

        // 保存更新后的文档到ES
        articleESRepository.save(po);
        log.debug("文章更新业务处理完成");

        // 转换为VO对象返回
        ArticleVO vo = new ArticleVO();
        BeanUtils.copyProperties(po, vo);
        return vo;
    }

    @Override
    public void deleteArticle(String id) {
        articleESRepository.deleteById(id);
    }

    /**
     * 将ArticleSearchPO的分页结果转换为ArticleActionVO的分页结果
     */
    private PageResult<ArticleActionVO> convertToActionPageResult(PageInfo<ArticleSearchPO> pageInfo) {
        PageResult<ArticleActionVO> pageResult = new PageResult<>();
        pageResult.setPageNo(pageInfo.getPageNum());
        pageResult.setPageSize(pageInfo.getPageSize());
        pageResult.setTotal(pageInfo.getTotal());
        
        List<ArticleActionVO> vos = new ArrayList<>();
        List<ArticleSearchPO> pos = pageInfo.getList();
        if (CollectionUtils.isNotEmpty(pos)) {
            vos = pos.stream().map(po -> {
                ArticleActionVO vo = new ArticleActionVO();
                vo.setId(String.valueOf(po.getId()));
                vo.setArticleId(po.getId());
                vo.setArticleTitle(po.getArticleTitle());
                vo.setArticleCover(po.getArticleCover());
                // 设置用户信息
                vo.setLikePerson(po.getArticleUsername());
                // TODO: 用户头像需要从用户服务获取
                return vo;
            }).collect(Collectors.toList());
        }
        
        pageResult.setObjects(vos);
        return pageResult;
    }


    // 构建行为记录基础对象
    private ActionSearchPO buildActionPO(ArticleSearchPO articleSearchPO, UserPrinciple userPrinciple) {
        ActionSearchPO actionSearchPO = new ActionSearchPO();
        actionSearchPO.setArticleUserId(articleSearchPO.getUserId());
        actionSearchPO.setArticleTitle(articleSearchPO.getArticleTitle());
        actionSearchPO.setArticleId(articleSearchPO.getId());
        actionSearchPO.setArticleLabel(articleSearchPO.getArticleLabel());
        actionSearchPO.setArticleType(categoryESRepository.findById(articleSearchPO.getArticleCategoryId()).get().getCategoryName());
        actionSearchPO.setBehaviorUserId(userPrinciple.getId());
        actionSearchPO.setCreateTime(new Date());
        return actionSearchPO;
    }

    // 处理单个行为类型
    private void singleBehavior(Integer behaviorType, ArticleSearchPO articleSearchPO,
                                       ActionSearchPO actionSearchPO, ArticleActionParam param) throws BusinessException {
        // 跳过无效行为类型
        if (behaviorType == null || behaviorType < 1 || behaviorType > 3) {
            log.warn("无效行为类型：{}，跳过处理", behaviorType);
            return;
        }

        // 行为类型差异化处理
        switch (behaviorType) {
            case 1: // 点赞
                articleSearchPO.setLikeCount(articleSearchPO.getLikeCount() + 1);
                actionSearchPO.setBehavior(1);
                break;
            case 2: // 收藏
                articleSearchPO.setFavoriteCount(articleSearchPO.getFavoriteCount() + 1);
                actionSearchPO.setBehavior(2);
                break;
            case 3: // 评论
                String comment = param.getComment();
                if (StringUtils.isBlank(comment)) {
                    throw new BusinessException("-1","评论不能为空");
                }
                actionSearchPO.setComment(comment);
                actionSearchPO.setBehavior(3);
                break;
        }

        // 统一保存行为记录和文章状态
        actionESRepository.save(actionSearchPO);
        articleESRepository.save(articleSearchPO);
        log.debug("用户行为记录完成，记录ID：{}", actionSearchPO.getId());
    }

    private Integer getMaxId() {
        // 注意：这种方法在高并发场景下可能不是完全准确
        // 但在您的场景下应该足够使用
        Iterable<ArticleSearchPO> allArticles = articleESRepository.findAll();
        Integer maxId = 0;
        for (ArticleSearchPO article : allArticles) {
            if (article.getId() != null && article.getId() > maxId) {
                maxId = article.getId();
            }
        }
        return maxId;
    }
}
